package org.csu.mybigpro.handler;

import org.csu.mybigpro.service.IflytekClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class SpeechWebSocketHandler extends AbstractWebSocketHandler {

    private static final Logger logger = LoggerFactory.getLogger(SpeechWebSocketHandler.class);

    private final ConcurrentHashMap<String, IflytekClient> sessionClients = new ConcurrentHashMap<>();

    @Autowired
    private IflytekClient.IflytekClientFactory iflytekClientFactory;

    // 封装一个创建新客户端的方法，方便复用
    private void createNewIflytekClient(WebSocketSession session) {
        try {
            IflytekClient client = iflytekClientFactory.create(
                    (text) -> {
                        try {
                            if (session.isOpen()) {
                                logger.info("收到最终识别结果: [{}], 准备发回前端。", text);
                                session.sendMessage(new TextMessage(text));
                            }
                        } catch (IOException e) {
                            logger.error("向前端发送消息失败", e);
                        }
                    }
            );
            sessionClients.put(session.getId(), client);
        } catch (Exception e) {
            logger.error("创建讯飞客户端失败", e);
            try {
                session.close(CloseStatus.SERVER_ERROR.withReason("Failed to create Iflytek client."));
            } catch (IOException ioException) {
                logger.error("关闭WebSocket会话失败", ioException);
            }
        }
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        logger.info("前端WebSocket连接成功, Session ID: {}", session.getId());
        // 注意：此处不再立即创建讯飞客户端，等收到第一段音频时再按需创建
    }

    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
        IflytekClient client = sessionClients.get(session.getId());

        // ======================= 【核心修改逻辑】 =======================
        // 如果客户端实例不存在，或者已存在但连接已关闭，则创建一个新的
        if (client == null || client.isClosed()) {
            logger.info("讯飞客户端不存在或已关闭，为 Session {} 创建新实例。", session.getId());
            createNewIflytekClient(session);
            client = sessionClients.get(session.getId()); // 获取新创建的实例
        }
        // ==========================================================

        // 确保客户端有效且连接处于打开状态后再发送音频
        if (client != null && client.isOpen()) {
            client.sendAudio(message.getPayload().array());
        }
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        if ("END".equals(message.getPayload())) {
            IflytekClient client = sessionClients.get(session.getId());
            if (client != null && client.isOpen()) {
                client.sendEnd();
            }
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        logger.info("前端WebSocket连接关闭, Session ID: {}, Status: {}", session.getId(), status);

        IflytekClient client = sessionClients.remove(session.getId());
        if (client != null && client.isOpen()) {
            client.close();
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        logger.error("WebSocket传输发生错误, Session ID: " + session.getId(), exception);
        afterConnectionClosed(session, CloseStatus.SERVER_ERROR);
    }
}